/*
 * @(#)XfspRulebaseSimplifierFactory.java        2004/08/01
 *
 * This file is part of Xfuzzy 3.1, a design environment for fuzzy logic
 * based systems.
 *
 * (c) 2000 IMSE-CNM. The authors may be contacted by the email address:
 *                    xfuzzy-team@imse.cnm.es
 *
 * Xfuzzy is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Xfuzzy is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

package xfuzzy.xfsp.model.rulebases;

import java.io.File;
import java.io.FileInputStream;
import xfuzzy.xfds.XfdsDataSet;
import xfuzzy.xfds.XfdsParser;

/**
 * <p> <b>Descripci�n:</b> f�brica de objetos que simplifican bases de reglas.
 * <p> <b>E-mail</b>: <ADDRESS>joragupra@us.es</ADDRRESS>
 * @author Jorge Agudo Praena
 * @version 1.4
 * @see IXfspRulebaseSimplifierFactory
 * @see IXfspRulebaseSimplifier
 * @see XfspModel
 * @see XfspRulebaseSimplifierDirector
 * @see XfspTabularSimplifier
 * @see XfspThresholdPruneSimplifier
 * @see XfspBestPruneSimplifier
 * @see XfspWorstPruneSimplifier
 *
 */
public class XfspRulebaseSimplifierFactory
implements IXfspRulebaseSimplifierFactory {

	//instancia de la clase (�nica en el sistema) con la que se implementa el
	//patr�n Singleton
	static private XfspRulebaseSimplifierFactory instance = null;

	/**
	 * <p> <b>Descripci�n:</b> contruye una f�brica de objetos que simplifican
	 * bases de reglas. Este constructor es privado a fin de que s�lo los objetos
	 * de la propia clase puedan llamarlo y los de otras clases hagan uso del
	 * m�todo <i>getInstance<\i>.
	 *
	 */
	private XfspRulebaseSimplifierFactory() {
	}

	/**
	 * <p> <b>Descripci�n:</b> devuelve una instancia de la clase. Este m�todo es
	 * la �nica forma de obtener f�bricas de simplificadores de reglas.
	 *
	 */
	public static XfspRulebaseSimplifierFactory getInstance() {
		//si no exist�a previamente una instancia de la clase...
		if (instance == null) {
			//...crea una nueva
			instance = new XfspRulebaseSimplifierFactory();
		}
		//devuelve una instancia de la clase
		return instance;
	}

	/**
	 * <p> <b>Descripci�n:</b> crea un objeto simplificador de bases de reglas
	 * del tipo indicado en el par�metro <i>method<\i> y al que se le pasan los
	 * argumengos contenidos en <i>args<\i>.
	 * @param method Tipo de simplificador de bases de reglas que se quiere
	 * obtener de la f�brica. Los tipos permitidos son: <i>Union<\i>,
	 * <i>Separation<\i>, <i>Tabular<\i>, <i>Threshold<\i>, <i>Best<\i> y
	 * <i>Worst<\i>.
	 * @param args Argumentos que hay que pasar al simplificador concreto que se
	 * cree.
	 *
	 */
	public IXfspRulebaseSimplifier create(String method, Object[] args) {
		//objeto que permite simplificar bases de reglas
		IXfspRulebaseSimplifier s = null;
		//si hay que simplificar la base de reglas por uni�n de reglas con mismos
		//consecuentes o por separaci�n de reglas que tienen OR en su
		//antecedente...
		if (method.equals("Union") || method.equals("Separation")) {
			//...crea un director que aplicar� el patr�n builder para ir construyendo
			//la nueva base de reglas
			s = new XfspRulebaseSimplifierDirector(method);
		}
		else if (method.equals("Tabular")) {
			s = new XfspTabularSimplifier( ( (Boolean) args[1]).booleanValue());
		}
		//en otro caso...
		else {
			//obtiene el m�todo de podado que debe utilizar
			String pruningMethod = (String) args[1];
			//obtiene el fichero de entrenamiento
			File patternFile = (File) args[2];

			//obtiene el fichero con los patrones de activaci�n de las entradas
			//para poder llevar a cabo el podado de la base de reglas
			XfdsDataSet pattern = null;
			try { 
				XfdsParser parser = new XfdsParser(new FileInputStream(patternFile)); 
				pattern = parser.parse();
			} catch(Exception ex) {}
			//si hay que podar las reglas cuya m�xima activaci�n est�n por debajo
			//de un umbral...
			if (pruningMethod.equals("Threshold")) {
				//..obtiene el umbral por debajo del cual las reglas con menor valor
				//m�ximo de activaci�n deben ser podadas de la base de reglas...
				double threshold = ( (Double) args[5]).doubleValue();
				//...y crea el simplificador de bases de reglas correspondiente
				s = new XfspThresholdPruneSimplifier(pattern.input, threshold);
			}
			//si el podado debe consistir en dejar las n mejores o en quitar las n
			//peores reglas seg�n su m�xima activaci�n...
			else {
				//...obtiene el n�mero de reglas que deben quedar o se deben quitar
				//de la base de reglas despu�s del podado de la base de reglas
				int numRules = ( (Integer) args[5]).intValue();
				//si deben quedar tras el podado en la base de reglas s�lo las n
				//mejores...
				if (pruningMethod.equals("Best")) {
					//...la variable 'numRules' indica cu�ntas deben quedar
					s = new XfspBestPruneSimplifier(pattern.input, numRules);
				}
				//...y si debe quitar las n peores
				else if (pruningMethod.equals("Worst")) {
					//...la variable 'numRules' indica cu�ntas hay que eliminar
					s = new XfspWorstPruneSimplifier(pattern.input, numRules);
				}
			}
		}
		//devuelve el simplificador de bases de reglas creado
		return s;
	}
}
